package com.ssy.lingxi.platform.manage.serviceimpl.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.basic.UserLoginSourceEnum;
import com.ssy.lingxi.common.constant.manage.ShopEnvironmentEnum;
import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.model.dto.MemberAndRoleIdDTO;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberInnerControllerFeign;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignQueryVO;
import com.ssy.lingxi.platform.manage.api.model.dto.shop.SelfBusinessShopLogoDTO;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.SelfBusinessShopLogoVO;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.entity.base.*;
import com.ssy.lingxi.platform.manage.model.request.shop.ShopAllAndSuperiorRequest;
import com.ssy.lingxi.platform.manage.model.request.shop.ShopAllReq;
import com.ssy.lingxi.platform.manage.model.response.SelfShopListResp;
import com.ssy.lingxi.platform.manage.repository.ShopRepository;
import com.ssy.lingxi.platform.manage.repository.ShopRuleRepository;
import com.ssy.lingxi.platform.manage.repository.SiteRepository;
import com.ssy.lingxi.platform.manage.repository.SiteShopRepository;
import com.ssy.lingxi.platform.manage.service.web.IShopWebService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * web - 商城 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2021/09/26
 */
@Service
public class ShopWebServiceImpl implements IShopWebService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private SiteRepository siteRepository;
    @Resource
    private ShopRepository shopRepository;
    @Resource
    private SiteShopRepository siteShopRepository;
    @Resource
    private ShopRuleRepository shopRuleRepository;
    @Resource
    private MemberInnerControllerFeign memberInnerControllerFeign;

    @Override
    public Wrapper<List<SelfShopListResp>> selfShopList(String shopName) {
        //获取自营商城
        QShop shop = QShop.shop;
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(shop.self.eq(CommonBooleanEnum.YES.getCode()));
        predicates.and(shop.state.eq(CommonBooleanEnum.YES.getCode()));
        if (StringUtils.isNotBlank(shopName)) {
            predicates.and(shop.name.like("%" + shopName + "%"));
        }
        List<Shop> shopList = jpaQueryFactory.select(shop).from(shop).where(predicates).orderBy(shop.id.asc()).fetch();
        if (CollectionUtil.isEmpty(shopList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //获取商城关联的站点
        List<SiteShop> siteShopList = siteShopRepository.findByShopIdIn(
                shopList.stream().map(Shop::getId).collect(Collectors.toList())
        );
        if (CollectionUtil.isEmpty(siteShopList)) {
            return Wrapper.success(new ArrayList<>());
        }
        List<Long> siteIdList = siteShopList.stream().map(SiteShop::getSiteId).collect(Collectors.toList());

        //获取站点
        List<Site> siteList = siteRepository.findAllById(siteIdList);

        //封装
        List<SelfShopListResp> selfShopListRespList = shopList.stream().map(a -> {
            //拷贝
            SelfShopListResp selfShopListResp = new SelfShopListResp();
            BeanUtils.copyProperties(a, selfShopListResp);

            //封装站点域名
            siteShopList.stream().filter(ss ->
                    ss.getShopId().equals(a.getId())
            ).findFirst().flatMap(siteShop ->
                    siteList.stream().filter(s ->
                            s.getId().equals(siteShop.getSiteId())
                    ).findFirst()
            ).ifPresent(site ->
                    selfShopListResp.setDomainName(site.getDomainName())
            );

            return selfShopListResp;
        }).collect(Collectors.toList());

        return Wrapper.success(selfShopListRespList);
    }

    @Override
    public Wrapper<List<Shop>> all(ShopAllReq req, UserLoginCacheDTO user) {
        //根据站点ID获取站点关联的商城
        List<SiteShop> siteShopList = siteShopRepository.findBySiteId(req.getSiteId());
        if (CollectionUtil.isEmpty(siteShopList)) {
            return Wrapper.success(new ArrayList<>());
        }
        List<Shop> shopList = shopRepository.findByIdInAndState(
                siteShopList.stream().map(SiteShop::getShopId).collect(Collectors.toList()),
                CommonBooleanEnum.YES.getCode()
        );

        //筛选出非自营的商城ID
        List<Long> shopIdList = shopList.stream().filter(shop ->
                shop.getSelf().equals(CommonBooleanEnum.NO.getCode())
        ).map(Shop::getId).collect(Collectors.toList());
        //筛选出自营的商城ID
        List<Long> selfShopIdList = shopList.stream().filter(shop ->
                shop.getSelf().equals(CommonBooleanEnum.YES.getCode())
        ).map(Shop::getId).collect(Collectors.toList());

        //平台（不需要自营商城）
        if (user.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_MANAGEMENT_PLATFORM.getCode())) {
            selfShopIdList.clear();
        }
        Long memberId = null;
        Long roleId = null;
        if (req.getMemberId() != null && req.getRoleId() != null) {
            memberId = req.getMemberId();
            roleId = req.getRoleId();
        }
        //商家（需要自营商城且筛选出属于自己的自营商城）&&服务消费者没有自营商城
        if (user.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_WEB.getCode()) && RoleTypeEnum.SERVICE_PROVIDER.getCode().equals(user.getMemberRoleType())) {
            memberId = user.getMemberId();
            roleId = user.getMemberRoleId();
            ShopRule shopRule = shopRuleRepository.findByMemberIdAndMemberRoleIdAndStatus(
                    memberId,
                    roleId,
                    CommonBooleanEnum.YES.getCode()
            );
            if (shopRule != null && CollectionUtil.isNotEmpty(shopRule.getShopList())) {
                List<Long> ids = shopRule.getShopList().stream().filter(a ->
                        a.getState().equals(CommonBooleanEnum.YES.getCode())
                ).map(ShopRuleDetail::getShopId).collect(Collectors.toList());
                selfShopIdList = selfShopIdList.stream().filter(ids::contains).collect(Collectors.toList());
            } else {
                selfShopIdList.clear();
            }
        }

        //将商城id聚合一起
        shopIdList.addAll(selfShopIdList);

        //根据条件获取商城
        QShop shop = QShop.shop;

        //条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(shop.state.eq(CommonBooleanEnum.YES.getCode()));
        predicates.and(shop.id.in(shopIdList));

        //商城环境
        if (req.getEnvironment() != null) {
            predicates.and(shop.environment.eq(req.getEnvironment()));
        }
        //商城类型
        if (req.getType() != null) {
            predicates.and(shop.type.eq(req.getType()));
        }
        //是否按当会员类型筛选
        if (req.getHasMemberType() != null && req.getHasMemberType().equals(CommonBooleanEnum.YES.getCode())) {
            if (user.getMemberType().equals(MemberTypeEnum.MERCHANT.getCode()) || user.getMemberType().equals(MemberTypeEnum.MERCHANT_PERSONAL.getCode())) {
                predicates.and(shop.type.eq(ShopTypeEnum.ENTERPRISE.getCode()));
            }
            if (user.getMemberType().equals(MemberTypeEnum.CHANNEL.getCode()) || user.getMemberType().equals(MemberTypeEnum.CHANNEL_PERSONAL.getCode())) {
                predicates.and(shop.type.in(ShopTypeEnum.getChannelAndChannelSelf()));
            }
        }

        //获取商城
        JPAQuery<Shop> jpaQuery = jpaQueryFactory.select(shop).from(shop).where(predicates);
        List<Shop> list = jpaQuery.orderBy(shop.id.asc()).fetch();
        //获取当前会员自己设置的自营商城的名称
        if (selfShopIdList.size() > 0 && memberId != null && roleId != null) {
            QShopRule qShopRule = QShopRule.shopRule;
            QShopRuleDetail qShopRuleDetail = QShopRuleDetail.shopRuleDetail;
            List<ShopRuleDetail> detailList = jpaQueryFactory.from(qShopRule)
                    .select(qShopRuleDetail)
                    .join(qShopRuleDetail).on(qShopRule.id.eq(qShopRuleDetail.shopRule.id))
                    .where(qShopRule.memberId.eq(memberId).and(qShopRule.memberRoleId.eq(roleId)))
                    .where(qShopRuleDetail.state.eq(CommonBooleanEnum.YES.getCode()))
                    .orderBy(qShopRuleDetail.shopId.asc())
                    .fetch();
            Map<Long, ShopRuleDetail> shopNameMap = detailList.stream().collect(Collectors.toMap(ShopRuleDetail::getShopId, ShopRuleDetail -> ShopRuleDetail));
            list.stream().filter(p -> shopNameMap.containsKey(p.getId())).forEach(p -> {
                ShopRuleDetail shopRuleDetail = shopNameMap.get(p.getId());
                p.setId(shopRuleDetail.getId());
                p.setName(shopRuleDetail.getName());
            });
        }

        return Wrapper.success(list);
    }

    @Override
    public Wrapper<List<Shop>> allShop(ShopAllAndSuperiorRequest req, UserLoginCacheDTO user) {
        //根据站点ID获取站点关联的商城
        List<SiteShop> siteShopList = siteShopRepository.findBySiteId(req.getSiteId());
        if (CollectionUtil.isEmpty(siteShopList)) {
            return Wrapper.success(new ArrayList<>());
        }
        List<Shop> shopList = shopRepository.findByIdInAndStateAndSelf(
                siteShopList.stream().map(SiteShop::getShopId).collect(Collectors.toList()),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.NO.getCode()
        );
        //筛选出非自营的商城ID
        List<Long> shopIdList = shopList.stream().map(Shop::getId).collect(Collectors.toList());
        //获取上级会员的全部自营商城
        //调用会员服务 ->获取当前会员的全部上级会员
        MemberFeignVO memberFeignVO = new MemberFeignVO();
        memberFeignVO.setMemberId(user.getMemberId());
        memberFeignVO.setRoleId(user.getMemberRoleId());
        Wrapper<List<MemberFeignQueryVO>> listUpperMembers = memberInnerControllerFeign.listUpperMembers(memberFeignVO);
        List<MemberFeignQueryVO> membersData = listUpperMembers.getData();
        //根据条件获取商城
        QShop shop = QShop.shop;
        //条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(shop.state.eq(CommonBooleanEnum.YES.getCode()));
        predicates.and(shop.id.in(shopIdList));

        //商城环境
        if (req.getEnvironment() != null) {
            predicates.and(shop.environment.eq(req.getEnvironment()));
        }
        //商城类型
        if (req.getType() != null) {
            predicates.and(shop.type.eq(req.getType()));
        }
        //是否按当会员类型筛选
        if (req.getHasMemberType() != null && req.getHasMemberType().equals(CommonBooleanEnum.YES.getCode())) {
            if (user.getMemberType().equals(MemberTypeEnum.MERCHANT.getCode()) || user.getMemberType().equals(MemberTypeEnum.MERCHANT_PERSONAL.getCode())) {
                predicates.and(shop.type.eq(ShopTypeEnum.ENTERPRISE.getCode()));
            }
            if (user.getMemberType().equals(MemberTypeEnum.CHANNEL.getCode()) || user.getMemberType().equals(MemberTypeEnum.CHANNEL_PERSONAL.getCode())) {
                predicates.and(shop.type.in(ShopTypeEnum.getChannelAndChannelSelf()));
            }
        }
        //step1->获取企业商城
        JPAQuery<Shop> jpaQuery = jpaQueryFactory.select(shop).from(shop).where(predicates);
        List<Shop> list = jpaQuery.orderBy(shop.id.asc()).fetch();
        //step2->获取当前会员以及上级会员自己设置的自营商城的名称
        QShopRule qShopRule = QShopRule.shopRule;
        QShopRuleDetail qShopRuleDetail = QShopRuleDetail.shopRuleDetail;
        //拼接条件
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qShopRuleDetail.state.eq(CommonBooleanEnum.YES.getCode()));
        //商家（需要自营商城且筛选出属于自己的自营商城）&&服务消费者没有自营商城
        if (user.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_WEB.getCode()) && RoleTypeEnum.SERVICE_PROVIDER.getCode().equals(user.getMemberRoleType())) {
            builder.and(qShopRule.memberRoleId.eq(user.getMemberRoleId()).and(qShopRule.memberId.eq(user.getMemberId())));
        }
        if (!CollectionUtils.isEmpty(membersData)) {
            membersData.forEach(e -> builder.or(qShopRule.memberId.eq(e.getMemberId()).and(qShopRule.memberRoleId.eq(e.getRoleId()))));
        }
        List<ShopRuleDetail> detailList = jpaQueryFactory.from(qShopRule)
                .select(qShopRuleDetail)
                .join(qShopRuleDetail).on(qShopRule.id.eq(qShopRuleDetail.shopRule.id))
                .where(builder)
                .orderBy(qShopRuleDetail.shopId.asc())
                .fetch();
        List<Shop> selfShops = detailList.stream().map(d -> BeanUtil.copyProperties(d, Shop.class)).collect(Collectors.toList());
        list.addAll(selfShops);
        //过滤id小于1000的自营商城
        return Wrapper.success(list.stream().filter(s->!(s.getSelf() != null && s.getSelf() == 1 && s.getId() < 1000)).collect(Collectors.toList()));
    }

    @Override
    public Wrapper<List<Shop>> findWebEnterpriseSelfShop(Long siteId, UserLoginCacheDTO sysUser) {

        List<Shop> shopList = new ArrayList<>();
        if (sysUser == null) {
            return Wrapper.success(shopList);
        }
        QShopRule qShopRule = QShopRule.shopRule;
        QShopRuleDetail qShopRuleDetail = QShopRuleDetail.shopRuleDetail;
        List<ShopRuleDetail> detailList = jpaQueryFactory.from(qShopRule)
                .select(qShopRuleDetail)
                .join(qShopRuleDetail).on(qShopRule.id.eq(qShopRuleDetail.shopRule.id))
                .where(qShopRule.memberId.eq(sysUser.getMemberId()).and(qShopRule.memberRoleId.eq(sysUser.getMemberRoleId())))
                .where(qShopRuleDetail.state.eq(CommonBooleanEnum.YES.getCode()), qShopRuleDetail.environment.eq(ShopEnvironmentEnum.WEB.getCode()))
                .orderBy(qShopRuleDetail.shopId.asc())
                .fetch();
        if (detailList.size() > 0) {
            shopList = detailList.stream().map(d -> {
                Shop shop = new Shop();
                BeanUtils.copyProperties(d, shop);
                return shop;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(shopList);
    }

    @Override
    public Wrapper<List<ShopRuleDetail>> findAppSelfShopByCurrMember(UserLoginCacheDTO user) {
        ShopRule shopRule = shopRuleRepository.findByMemberIdAndMemberRoleIdAndStatus(
                user.getMemberId(),
                user.getMemberRoleId(),
                CommonBooleanEnum.YES.getCode()
        );
        if (shopRule == null || CollectionUtil.isEmpty(shopRule.getShopList())) {
            return Wrapper.success(new ArrayList<>());
        }

        List<ShopRuleDetail> shopRuleDetailList = shopRule.getShopList().stream().filter(a ->
                a.getState().equals(CommonBooleanEnum.YES.getCode())
                        && a.getEnvironment().equals(ShopEnvironmentEnum.APP.getCode())
        ).peek(a -> a.setShopRule(null)).collect(Collectors.toList());

        return Wrapper.success(shopRuleDetailList);
    }

    @Override
    public Wrapper<List<Long>> findSelfBusinessShopId(MemberAndRoleIdDTO dto) {
        ShopRule shopRule = shopRuleRepository.findByMemberIdAndMemberRoleIdAndStatus(
                dto.getMemberId(),
                dto.getRoleId(),
                CommonBooleanEnum.YES.getCode()
        );

        List<Long> idList = new ArrayList<>();
        if (shopRule != null && CollectionUtil.isNotEmpty(shopRule.getShopList())) {
            idList = shopRule.getShopList().stream().filter(a ->
                    a.getState().equals(CommonBooleanEnum.YES.getCode())
            ).map(ShopRuleDetail::getId).collect(Collectors.toList());
        }

        return Wrapper.success(idList);
    }

    @Override
    public Wrapper<List<SelfBusinessShopLogoVO>> findSelfBusinessShopLogo(SelfBusinessShopLogoDTO dto) {
        //根据会员ID获取自营商家
        List<ShopRule> shopRuleList = shopRuleRepository.findByMemberIdInAndStatus(
                dto.getList().stream().map(MemberAndRoleIdDTO::getMemberId).collect(Collectors.toList()),
                CommonBooleanEnum.YES.getCode()
        );

        //组装
        List<SelfBusinessShopLogoVO> list = dto.getList().stream().map(a -> {
            SelfBusinessShopLogoVO vo = new SelfBusinessShopLogoVO();
            vo.setMemberId(a.getMemberId());
            vo.setMemberRoleId(a.getRoleId());

            ShopRule shopRule = shopRuleList.stream().filter(b ->
                    b.getMemberId().equals(a.getMemberId())
            ).findFirst().orElse(null);
            if (shopRule != null) {
                ShopRuleDetail shopRuleDetail = shopRule.getShopList().stream().filter(c ->
                        c.getId().equals(dto.getShopId())
                ).findFirst().orElse(null);
                vo.setLogoUrl(shopRuleDetail != null ? shopRuleDetail.getLogoUrl() : null);
                vo.setName(shopRuleDetail != null ? shopRuleDetail.getName() : null);
            }

            return vo;
        }).collect(Collectors.toList());

        return Wrapper.success(list);
    }

    @Override
    public Wrapper<List<ShopRuleDetail>> findAppletsSelfShopByCurrMember(UserLoginCacheDTO user) {
        ShopRule shopRule = shopRuleRepository.findByMemberIdAndMemberRoleIdAndStatus(
                user.getMemberId(),
                user.getMemberRoleId(),
                CommonBooleanEnum.YES.getCode()
        );
        if (shopRule == null || CollectionUtil.isEmpty(shopRule.getShopList())) {
            return Wrapper.success(new ArrayList<>());
        }

        List<ShopRuleDetail> shopRuleDetailList = shopRule.getShopList().stream().filter(a ->
                a.getState().equals(CommonBooleanEnum.YES.getCode())
                        && a.getEnvironment().equals(ShopEnvironmentEnum.APPLETS.getCode())
        ).peek(a -> a.setShopRule(null)).collect(Collectors.toList());

        return Wrapper.success(shopRuleDetailList);
    }
}
